#ifndef __THREAD_HPP
#define __THREAD_HPP

#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>
#include <functional>
#include <assert.h>
template <class T>
using func_t = std::function<void(T &)>;

template <class T>
class Thread
{
public:
    void Execute()
    {
        _func(_data);
    }

public:
    // 构造函数
    Thread(func_t<T> func, T &data, const std::string &name = "thread-none")
        : _data(data), _func(func), _threadname(name)
    {
        int n = pthread_create(&_tid, nullptr, threadroutine, this);
        assert(!n);
    }
    // 调用顺序：Start->threadroutine->Execute->_func
    static void *threadroutine(void *args)
    {
        Thread<T> *self = static_cast<Thread<T> *>(args);
        self->Execute();
        return nullptr;
    }
    // 线程分离
    void Detach()
    {
        int n = pthread_detach(_tid);
        assert(!n);
    }
    // 线程等待
    void Join()
    {
        int n = pthread_join(_tid, nullptr);
        assert(!n);
    }
    std::string name()
    {
        return _threadname;
    }
    ~Thread()
    {}

protected:
    pthread_t _tid;
    std::string _threadname;
    T &_data;
    func_t<T> _func;
};
#endif
